package cn.cdutetc.library.common;

import cn.cdutetc.library.common.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/**
 * Apache POI Excel工具类
 */
@Slf4j
public class PoiExcelUtils {
    
    /**
     * 生成图书导入模板
     * @param response HTTP响应
     * @param fileName 文件名
     */
    public static void generateBookTemplate(HttpServletResponse response, String fileName) {
        if (response == null || fileName == null) {
            throw new BizException("参数不能为空");
        }
        
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("图书导入模板");
            
            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {
                "ISBN号*", "图书名称*", "作者*", "出版社", "出版日期(格式:2023-01-01)", 
                "分类名称*", "图书价格", "总册数*", "图书位置", "图书简介"
            };
            
            // 设置标题样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerFont.setFontHeightInPoints((short) 12);
            headerStyle.setFont(headerFont);
            headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            headerStyle.setBorderTop(BorderStyle.THIN);
            headerStyle.setBorderRight(BorderStyle.THIN);
            headerStyle.setBorderLeft(BorderStyle.THIN);
            
            // 创建标题单元格
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 创建示例数据行
            Row exampleRow1 = sheet.createRow(1);
            String[] exampleData1 = {
                "9787111641247", "Java编程思想", "Bruce Eckel", "机械工业出版社", "2023-01-01",
                "计算机科学", "108.00", "5", "科技区A架3层", "一本经典的Java编程书籍"
            };
            
            for (int i = 0; i < exampleData1.length; i++) {
                Cell cell = exampleRow1.createCell(i);
                cell.setCellValue(exampleData1[i]);
            }
            
            // 创建第二个示例数据行
            Row exampleRow2 = sheet.createRow(2);
            String[] exampleData2 = {
                "9787302511234", "Spring Boot实战", "张三", "清华大学出版社", "2023-06-15",
                "计算机科学", "89.00", "3", "科技区B架2层", "Spring Boot开发指南"
            };
            
            for (int i = 0; i < exampleData2.length; i++) {
                Cell cell = exampleRow2.createCell(i);
                cell.setCellValue(exampleData2[i]);
            }
            
            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
                // 设置最小列宽
                int currentWidth = sheet.getColumnWidth(i);
                if (currentWidth < 3000) {
                    sheet.setColumnWidth(i, 3000);
                }
            }
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            
            String encodedFileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
            
            // 写入响应流
            workbook.write(response.getOutputStream());
            
        } catch (Exception e) {
            log.error("生成Excel模板失败: {}", e.getMessage(), e);
            throw new BizException("生成Excel模板失败: " + e.getMessage());
        }
    }
    
    /**
     * 生成图书信息导出Excel
     * @param response HTTP响应
     * @param fileName 文件名
     * @param bookData 图书数据列表
     */
    public static void generateBookExport(HttpServletResponse response, String fileName, List<Map<String, Object>> bookData) {
        if (response == null || fileName == null || bookData == null) {
            throw new BizException("参数不能为空");
        }
        
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("图书信息");
            
            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {
                "ISBN号", "图书名称", "作者", "出版社", "出版日期", 
                "分类名称", "图书价格", "总册数", "在库数量", "借出数量", "异常数量", "图书位置", "图书简介"
            };
            
            // 设置标题样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerFont.setFontHeightInPoints((short) 12);
            headerStyle.setFont(headerFont);
            headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            headerStyle.setBorderTop(BorderStyle.THIN);
            headerStyle.setBorderRight(BorderStyle.THIN);
            headerStyle.setBorderLeft(BorderStyle.THIN);
            
            // 创建标题单元格
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 创建数据行
            int rowNum = 1;
            for (Map<String, Object> book : bookData) {
                Row row = sheet.createRow(rowNum++);
                
                row.createCell(0).setCellValue(getStringValue(book.get("isbn")));
                row.createCell(1).setCellValue(getStringValue(book.get("bookName")));
                row.createCell(2).setCellValue(getStringValue(book.get("author")));
                row.createCell(3).setCellValue(getStringValue(book.get("publisher")));
                row.createCell(4).setCellValue(getStringValue(book.get("publishDate")));
                row.createCell(5).setCellValue(getStringValue(book.get("categoryName")));
                row.createCell(6).setCellValue(getStringValue(book.get("price")));
                row.createCell(7).setCellValue(getStringValue(book.get("totalCopies")));
                row.createCell(8).setCellValue(getStringValue(book.get("inStockCount")));
                row.createCell(9).setCellValue(getStringValue(book.get("borrowedCount")));
                row.createCell(10).setCellValue(getStringValue(book.get("abnormalCount")));
                row.createCell(11).setCellValue(getStringValue(book.get("location")));
                row.createCell(12).setCellValue(getStringValue(book.get("description")));
            }
            
            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
                // 设置最小列宽
                int currentWidth = sheet.getColumnWidth(i);
                if (currentWidth < 3000) {
                    sheet.setColumnWidth(i, 3000);
                }
            }
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            
            String encodedFileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
            
            // 写入响应流
            workbook.write(response.getOutputStream());
            
        } catch (Exception e) {
            log.error("生成Excel导出失败: {}", e.getMessage(), e);
            throw new BizException("生成Excel导出失败: " + e.getMessage());
        }
    }
    
    /**
     * 安全获取字符串值
     */
    private static String getStringValue(Object value) {
        return value != null ? value.toString() : "";
    }
}
